package nl.scalasim
package util

/**
 * Advertisements keep track of which actors have which goods available.
 *
 * @author Yigal Duppen
 * @since Nov 18, 2010
 */
class Advertisements[A] {

  type Adv = (A, Goods, Int)

  private var advertisements: List[Adv] = List()

  /**
   * Advertise that <code>a</code> has <code>m</code> goods available.
   * Previous advertisements regarding <code>a</code> are invalidated. 
   */
  def advertise(a: A, m: Map[Goods, Amount]): Unit = {
    val newAdverts = for (entry <- m.iterator) yield (a, entry._1, entry._2.value) 
    advertisements = (advertisements filter { t: Adv => t._1 != a }) ++ newAdverts
  }

  /**
   * Find all A's which have advertised that they have at least the
   * requested amount of at least one of the goods available. 
   */
  def find(g: List[(Goods, Int)]): Set[A] = {
    val request: Map[Goods, Int] = scala.collection.immutable.ListMap(g map { t => t._1 -> t._2 } : _*)
    val matchingAdvertisements = advertisements filter {adv => request.getOrElse(adv._2, Integer.MAX_VALUE) <= adv._3}
    (matchingAdvertisements map { t => t._1 }).toSet
  }

}